package com.lin.demo.aspacts;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.lin.demo.annotations.LocalLock;
import com.lin.demo.config.AppException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.http.HttpStatus;

import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;

/**
 * @Author zimingl
 * @Date 2023/4/1 13:10
 * @Description: guava 本地锁
 */
//@Aspect
//@Component
@Slf4j
public class GuavaLockInterceptor {
    //定义缓存，设置最大缓存数
    Cache<Object, Object> CACHE = CacheBuilder.newBuilder().maximumSize(100).expireAfterWrite(1000, TimeUnit.SECONDS).build();

    @Around("execution(public * *(..))  && @annotation(com.lin.demo.annotations.LocalLock)")
    public Object interceptor(ProceedingJoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        LocalLock localLock = method.getAnnotation(LocalLock.class);
        String key = getKey(localLock.key(), joinPoint.getArgs());
        if (!StringUtils.isEmpty(key)) {
            if (CACHE.getIfPresent(key) != null) {
                throw new AppException(HttpStatus.BAD_REQUEST.value(), "请勿重复提交！");
            }
            CACHE.put(key, key);
        }
        try {
            return joinPoint.proceed();
        } catch (Throwable throwable) {
            log.error(throwable.getMessage(), throwable);
        }
        return null;
    }

    private String getKey(String keyExpress, Object[] args) {
        for (int i = 0; i < args.length; i++) {
            keyExpress = keyExpress.replace("arg[" + i + "]", args[i].toString());
        }
        return keyExpress;
    }
}
